# $Id: msg.py 10 2006-06-17 19:41:19Z niels $
#
# Copyright (C) 2006  Niels de Vos
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA
#

import os
import re
from time import time
import logging
import sys
import libomd

__log = None
__log = logging.getLogger('msg')
if not __log.handlers:
    __log.addHandler(logging.StreamHandler(sys.stderr))

class Message:
    
    def __init__(self, _dst = None):
        self.omus = 'alpha'
        self.src = None
        self.dst = _dst
        self.timestamp = time()
    
    def __str__(self):
        return '<type=%s, src=%s, dst=%s, stamp=%s>' % (self.__class__, self.src, self.dst, self.timestamp)

class Request(Message):
    def createReply(self):
        pass

class Reply(Message):
    def __init__(self, _req):
        Message.__init__(self)
        self.src = None
        self.dst = _req.src

class InfoRequest(Request):
    def createReply(self):
        return InfoReply(self)

class InfoReply(Reply):
    cpuInfo = None
    
    def __init__(self, _req):
        Reply.__init__(self, _req)
        self.meminfo = self.getMem()
        self.cpuinfo = self.getCPUs()
        #self.load = self.getLoad();

    def getCPUs(self):
        global __log
        cpulist = None
        try:
            cpuinfo = file('/proc/cpuinfo', 'r')
            cpu = -1
            cpulist = dict()
            for l in filter(lambda i: i.strip() != '', cpuinfo.readlines()):
                # seperate key/value
                (k, v) = re.split(':', l, 1)
                k = k.strip()
                v = v.strip()
                if re.match('^processor$', k, re.IGNORECASE):
                    cpu = int(v)
                    cpulist[cpu] = dict()
                else:
                    if re.match('^flags$', k, re.IGNORECASE):
                        v = re.split('\s+', v)
                    cpulist[cpu][k] = v
            cpuinfo.close()
        except OSError, e:
            __log.error('Error reading /proc/cpuinfo:\n%s\n' % e)
            
        return cpulist
    
    def getLoad(self):
        global __log
        load = None
        try:
            loadinfo = file('/proc/loadavg', 'r')
            mem = dict()
            for l in filter(lambda i: i.strip()!= '', loadinfo.readlines()):
                # seperate key/value
                   (a,b) = re.split(' ',1)
                a = a.strip()
                #v = v.strip()
                load = a
            loadinfo.close()
        except OSError, e:
            __log.error('Error reading /proc/loadavg:\n%s\n' % e)

        return load        
    
    def getMem(self):
        global __log
        mem = None
        try:
            meminfo = file('/proc/meminfo', 'r')
            mem = dict()
            for l in filter(lambda i: re.match('^MemTotal[\s:]', i, re.IGNORECASE), meminfo.readlines()):
                # seperate key/value
                   (k, v) = re.split(':', l, 1)
                k = k.strip()
                v = v.strip()
                mem = v
            meminfo.close()
        except OSError, e:
            __log.error('Error reading /proc/meminfo:\n%s\n' % e)

        return mem

class MigrationRequest(Request):
    proc = None
    
    def __init__(self, _dst, _proc):
        Request.__init__(self, _dst)
        self.proc = _proc
        
    def createReply(self):
        return MigrationReply(self)
        
class MigrationReply(Reply):
    pid = None
    accept = None
    
    def __init__(self, _req):
        Reply.__init__(self, _req)
        self.proc = _req.proc

class StatusMsg(Message):

    def __init__(self):
        Message.__init__(self)
        self.load = self.readLoad()
        self.meminfo = self.readMemInfo()
    
    def readLoad(self):
        global __log
        load = None
        try:
            loadavg = file('/proc/loadavg', 'r')
            load = re.split('\s+', loadavg.readline())
            load = filter(lambda i: i != '', load)
            loadavg.close()
        except OSError, e:
            __log.error('Error reading /proc/cpuinfo:\n%s\n' % e)
        return load
    
    def readMemInfo(self):
        global __log
        mem = None
        try:
            meminfo = file('/proc/meminfo', 'r')
            mem = dict()
            for l in filter(lambda i: i.strip() != '', meminfo.readlines()):
                # seperate key/value
                   (k, v) = re.split(':', l, 1)
                k = k.strip()
                v = v.strip()
                mem[k] = v
        except OSError, e:
            __log.error('Error reading /proc/cpuinfo:\n%s\n' % e)
            
        return mem

